package com.tuanproject.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;


/**
 * 
 * @author TuanLe
 * 
 * @param <T>
 */
public abstract class GenericDAO<T> {

	protected T entity;

	@Autowired
	protected DataSource dataSource;

	/**
	 * get all object in database
	 * 
	 * @return List
	 * @throws SQLException
	 */
	public List<T> getAllObject() throws SQLException {

		String sql = "select * from " + entity.getClass().getSimpleName();
		List<T> list = new ArrayList<T>();
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		list = jdbcTemplate.query(sql, new RowMapper<T>() {
			@Override
			public T mapRow(ResultSet rs, int rowNum) throws SQLException {
				return getDataFromResultSet(rs, rowNum);
			}
		});
		return list;
	}

	/**
	 * get object with record number and page in database
	 * 
	 * @param recordNum
	 * @param page
	 * @return
	 * @throws SQLException
	 */
	public List<T> getAllObject(int recordNum, int page) throws SQLException {

		page = page >= 1 ? page : 1;
		int start = recordNum * (page - 1);
		String sql = "select * from " + entity.getClass().getSimpleName()
				+ " limit " + start + "," + recordNum;
		List<T> list = new ArrayList<T>();
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		list = jdbcTemplate.query(sql, new RowMapper<T>() {
			@Override
			public T mapRow(ResultSet rs, int rowNum) throws SQLException {
				return getDataFromResultSet(rs, rowNum);
			}
		});
		return list;
	}

	/**
	 * get Object by id
	 * 
	 * @param Id
	 * @return
	 * @throws SQLException
	 */
	public T getById(int id) throws SQLException {

		String sql = "select * from " + entity.getClass().getSimpleName()
				+ " where id = " + id;

		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		T object = jdbcTemplate.queryForObject(sql, new Object[] { id },
				new RowMapper<T>() {
					@Override
					public T mapRow(ResultSet rs, int rowNum)
							throws SQLException {
						return getDataFromResultSet(rs, rowNum);
					}
				});
		return object;
	}

	/**
	 * delete object by id
	 * 
	 * @param id
	 * @throws SQLException
	 */
	public void delete(int id) throws SQLException {
		String sql = "delete from " + entity.getClass().getSimpleName() + " where id = " + id;
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		jdbcTemplate.update(sql);
	}
	
	/**
	 * get data by ResultSet
	 * 
	 * @param rs
	 * @param rowNum
	 * @return
	 * @throws SQLException
	 */
	public abstract T getDataFromResultSet(ResultSet rs, int rowNum) throws SQLException;

}

